//------------------------------------------------------------------------------
// Include Files
//------------------------------------------------------------------------------
#include <windows.h>
#include <nkintr.h>
#include <tchddsi.h>
#include <tchddi.h>
#include <ceddk.h>

#include "args.h"
#include "ioctl_cfg.h"

#include "monahans.h"
#include "xllp_defs.h"
#include "xllp_mfp.h"
#include "xllp_ost.h"

#include "xllp_gpio.h"

#include "xllp_tsi_micco_B0.h"
#include "micco.h"

#include "xllp_intc.h"
#include "bsp_cfg.h"

#include "touch.h"


extern "C" const int MIN_CAL_COUNT = 25;

extern "C" HANDLE  hTouchPanelEvent; //ran ? 

extern "C" DWORD gdwTouchIstTimeout; // In Touch MDD

DWORD gIntrTouch        = SYSINTR_TOUCH;
DWORD gIntrTouchChanged = SYSINTR_TOUCH_CHANGED;

static volatile P_XLLP_OST_T  g_pOSTRegs=NULL;


HANDLE	g_hMiccoDrv=NULL; //TSI micco handle
HANDLE	g_PenDownEvent = NULL; //TSI ISR Event handle
HANDLE	g_TSI_X_Y_ReadyEvent = NULL; //TSI ISR Event handle

HANDLE  g_hTouchIST_TerminateEvent= NULL;
HANDLE	g_hTouchIST = NULL;    // touch screen IST

PEN_STATUS penStatus=PEN_STATUS_UP;

static INT g_prevX = 0;
static INT g_prevY = 0;

#define ABS(x)  ((x) >= 0 ? (x) : (-(x)))


#define TSP_MINX						75
#define TSP_MINY						65

#define TSP_MAXX						940
#define TSP_MAXY						950

//----------------------------------------------------------------------------------------
//shacharh
//----------------------------------------------------------------------------------------



//------------------------------------------------------------------------------
// Local Functions
//------------------------------------------------------------------------------

static BOOL SetMiccoTSIMode(MICOO_TSI_MODE mode)
{
    TOUCH_STATUS_T ret;
    if ( mode==TSI_PEN_DETECT)
    {
        //RETAILMSG(1,(TEXT("[TOUCH] Enter Pen Detect mode\r\n")));
        ret = ModifyMiccoReg(XLLP_MICCO_ADC_AUTO_CONTROL_2,PEN_DETECT_ENABLE_SET,AUTO_TSI_MASK_CLR,NULL);
    }
    else // TSI_AUTO
    { 
        //RETAILMSG(1,(TEXT("[TOUCH] Enter Auto mode\r\n")));
        ret = ModifyMiccoReg(XLLP_MICCO_ADC_AUTO_CONTROL_2,AUTO_TSI_ENABLE_SET,PEN_DETECT_MASK_CLR,NULL);
    }
    return ret==TOUCH_STATUS_SUCCESS;
}

static BOOL ClearMiccoTSI(void)
{
	
	BYTE reg[2];	//1st byte reg address 2nd byte reg val for IO micco regs
	BOOL ret_val;

	//shacharh to save prev val of micco tsi regs 
	BYTE	PrevAdcManControl_Val =0;

	//RETAILMSG(1, (TEXT("[TOUCH] +ClearMiccoTSI Start\r\n"))); 

	//restore ADC_MAN_CONTROL
	//get Micco reg adress:ADC_MAN_CONTROL
	reg[0] = XLLP_MICCO_ADC_MAN_CONTROL;
	ret_val = DeviceIoControl(g_hMiccoDrv, PIC_IO_GET_REG, reg,sizeof(BYTE), reg+1, sizeof(BYTE), NULL,NULL);
	if(!ret_val){
	    RETAILMSG(DEBUG_TOUCH,(TEXT("AllocateTouchPanelResources:+Cant get XLLP_MICCO_ADC_MAN_CONTROL\r\n")));
	    return(FALSE);		
	}

	PrevAdcManControl_Val = reg[1];
	
	reg[1] &= (LDO_ADC_ENABLE_MASK_CLR & MUX_MASK_CLR);
	PrevAdcManControl_Val &= LDO_ADC_ENABLE_SET;		//case LDO was prev set 
	reg[1] |= PrevAdcManControl_Val;

	//write to Micco HW:ADC_MAN_CONTROL
	ret_val = DeviceIoControl(g_hMiccoDrv, PIC_IO_SET_REG, reg,2*sizeof(BYTE), NULL, 0, NULL,NULL);
	if(!ret_val){
	    RETAILMSG(DEBUG_TOUCH,(TEXT("AllocateTouchPanelResources:+Cant set XLLP_MICCO_ADC_MAN_CONTROL\r\n")));
	    return(FALSE);
	}

	//---------------------------------------
	//restore ADC_AUTO_CONTROL_2
	//get Micco reg ADC_AUTO_CONTROL_2
	reg[0] = XLLP_MICCO_ADC_AUTO_CONTROL_2;
	ret_val = DeviceIoControl(g_hMiccoDrv, PIC_IO_GET_REG, reg,sizeof(BYTE), reg+1, sizeof(BYTE), NULL,NULL);
	if(!ret_val){
	    RETAILMSG(DEBUG_TOUCH,(TEXT("AllocateTouchPanelResources:+Cant get XLLP_MICCO_ADC_AUTO_CONTROL_2\r\n")));
	    return(FALSE);
	}

	reg[1] &= (PEN_DETECT_MASK_CLR & AUTO_TSI_MASK_CLR);
	//reg[1] |= PrevAdcAutoControl_2_Val;

	//set data to ADC_AUTO_CONTROL_2

	//write to Micco HW ADC_AUTO_CONTROL_2
	ret_val = DeviceIoControl(g_hMiccoDrv, PIC_IO_SET_REG, reg,2*sizeof(BYTE), NULL, 0, NULL,NULL);
	if(!ret_val){
	    RETAILMSG(DEBUG_TOUCH,(TEXT("AllocateTouchPanelResources:+Cant set XLLP_MICCO_ADC_AUTO_CONTROL_2\r\n")));
	    return(FALSE);
	}

	//RETAILMSG(1, (TEXT("[TOUCH] -ClearMiccoTSI End\r\n")));
	return(TRUE);
}

//----------------------------------------------------------------------------------------
// Set up \ re-arm OSMR interrupt to be used 
//----------------------------------------------------------------------------------------

static void EnableTouchTimerInterrupt(UINT32 TimeInterval)
{
    volatile UINT32 TimerMatch;

    //RETAILMSG(1,(TEXT("[touch] + EnableTouchTimerInterrupt \r\n")));

    // XLLI initializes oier and rtsr to zeros, so no further
    // initialization needs to be done.  Match timers and
    // alarms are disabled.
    //
    // Current usage of Match registers:
    //  M0 - Scheduler
    //  M1 - Touch Panel
    //  M2 - Profiler

    // Configure and arm the timer interrupt  to interrupt every specified system tick interval.
    //RETAILMSG(DEBUG_TOUCH,(_T("[touch] + Enable Touch Timer Interrupt Start\r\n")));

    //shachar TimerMatch = (g_pOSTRegs->oscr0 + TimeInterval); 
    TimerMatch = g_pOSTRegs->oscr0;
	
    if((TimerMatch + TimeInterval)<TimerMatch)  
    {
        RETAILMSG(DEBUG_TOUCH,(_T("[touch] + Touch Timer Roll Back!!!\r\n")));
        TimerMatch = (TimeInterval - (((1<<32)-1)-TimerMatch));//timer roll
    }
    else	
        TimerMatch += TimeInterval; 

	
    //XllpINTCEnableSource(XLLP_INTC_S_OST_M1,XLLP_TRUE);
    XllpOstConfigureTimer(g_pOSTRegs, MatchReg1, TimerMatch);

    //RETAILMSG(DEBUG_TOUCH,(_T("[TOUCH] - EnableTouchTimerInterrupt\r\n")));
    return;
}


//----------------------------------------------------------------------------------------
// Enable \ Disable  the TSI_Ready Interrupt 
//----------------------------------------------------------------------------------------

static BOOL EnableTSI_X_Y_ReadyInterrupt(void)
{
    BOOL ret=TRUE;
    DWORD	event = PIC_EVENT_TSI_READY;
    if ( g_TSI_X_Y_ReadyEvent ==NULL)  //only needed in the first time,
        ret= DeviceIoControl(g_hMiccoDrv, PIC_IO_GET_EVENT_HANDLE,&event,sizeof(DWORD), &g_TSI_X_Y_ReadyEvent, sizeof(DWORD), NULL,NULL);
    //enable the event in MICCO MASK Register
    if (ret)
        ret= DeviceIoControl(g_hMiccoDrv,PIC_IO_ENABLE_EVENT, &event,sizeof(DWORD), NULL, 0,NULL,NULL);
    return ret;
}

static BOOL DisableTSI_X_Y_ReadyInterrupt(void)
{
    DWORD event = PIC_EVENT_TSI_READY;
    return DeviceIoControl(g_hMiccoDrv,PIC_IO_DISABLE_EVENT, &event,sizeof(DWORD), NULL, 0,NULL,NULL);
}


//----------------------------------------------------------------------------------------
// Enable  the pen detect interrupt 
//----------------------------------------------------------------------------------------

static BOOL EnablePenDownInterrupt(void)
{
    BOOL ret=TRUE;
    DWORD	event = PIC_EVENT_ADC_PEN_DOWN;
    //RETAILMSG(1,(TEXT("[touch] + EnableTouchInterrupt\r\n")));
    //create event inside MICCO Driver, only needed once
    if ( g_PenDownEvent ==NULL)  //only needed in the first time,
        ret= DeviceIoControl(g_hMiccoDrv, PIC_IO_GET_EVENT_HANDLE,&event,sizeof(DWORD), &g_PenDownEvent, sizeof(DWORD), NULL,NULL);
    //enable the event in MICCO MASK Register
    if ( ret)
        ret= DeviceIoControl(g_hMiccoDrv,PIC_IO_ENABLE_EVENT, &event,sizeof(DWORD), NULL, 0,NULL,NULL);

    //RETAILMSG(1,(TEXT("[touch] - EnableTouchInterrupt\r\n")));
    return ret;
}


//----------------------------------------------------------------------------------------
//  Disable the pen detect interrupt 
//----------------------------------------------------------------------------------------
static BOOL DisablePenDownInterrupt(void)
{
    DWORD event = PIC_EVENT_ADC_PEN_DOWN;
    return DeviceIoControl(g_hMiccoDrv,PIC_IO_DISABLE_EVENT, &event,sizeof(DWORD), NULL, 0,NULL,NULL);
}

// --------------------------------------------
INT evaluateSample(USHORT *val,int maxError,INT *sample)
{
    LONG  diff;
    INT retval = TouchSampleValidFlag ;
    USHORT i;


    for (i=0; i<TOUCH_SAMPLES_NUMBER_PER_POINT;i++)
    {
	if (*(val+2*i)>=MAX_ADC_VAL) 
	{
		retval=TouchSampleIgnore;
		RETAILMSG(1, (L"Error: Sample is above max boundary value.\r\n"));
	}
    }
    
    if ( retval !=TouchSampleIgnore)
    {
        *sample=0;
        for (i=0; i<TOUCH_SAMPLES_NUMBER_PER_POINT;i++) 
            *sample+=*(val+2*i);
        *sample/=TOUCH_SAMPLES_NUMBER_PER_POINT;

        INT errCount = 0;

        for (i=0; i<TOUCH_SAMPLES_NUMBER_PER_POINT;i++)  
        {
		diff=*(val+2*i)-*sample;
		diff= diff>0 ? diff: -diff;
		if (diff>= maxError)  
		{
			errCount++;
			if(errCount > 5)
				retval = TouchSampleIgnore;
		}			
        }
    }
    return(retval);
}


void TSP_TransXY(INT *px, INT *py)
{
    //RETAILMSG(1, (L"before x cordinate(%d),  y cordinate(%d))\r\n",*px,*py));
	
    *px = *px - TSP_MINX;

    *py = *py - TSP_MINY;

    if (*px  <        0) *px = 0;
    if (*px >= TSP_MAXX) *px = TSP_MAXX - 1;

    if (*py  <        0) *py = 0;
    if (*py >= TSP_MAXY) *py = TSP_MAXY - 1;

    //RETAILMSG(1, (L"1x cordinate(%d),  y cordinate(%d))\r\n",*px,*py));
	
}


PEN_STATUS GetPenStatus()
{
	BOOL bPenDown,ret_val;
	ret_val = DeviceIoControl(g_hMiccoDrv, PIC_IO_GET_PEN_DOWN, NULL,0, &bPenDown, sizeof(BOOL), NULL,NULL);
	if(!ret_val)
	{
	    RETAILMSG(DEBUG_TOUCH,(TEXT("[TOUCH] ERROR - Cant get XLLP_TOUCH_STATUS_A\r\n")));
	    return PEN_STATUS_INIT;
	}

    return bPenDown?PEN_STATUS_DOWN:PEN_STATUS_UP;
}


TOUCH_STATUS_T ModifyMiccoReg(BYTE reg_address,BYTE set_mask,BYTE clear_mask,LPBYTE prevValue)
{
    BYTE reg[2];	
    reg[0] = reg_address;
    BOOL ret_val;
    ret_val = DeviceIoControl(g_hMiccoDrv, PIC_IO_GET_REG, reg,sizeof(BYTE), reg+1, sizeof(BYTE), NULL,NULL);
    if(!ret_val)
    {
        return TOUCH_STATUS_FAILURE;
    }
    //update original value
    if (prevValue!=NULL )
        *prevValue = reg[1];

    //set the masks
    reg[1]&= clear_mask;
    reg[1]|= set_mask;

    //write value to reg
    ret_val = DeviceIoControl(g_hMiccoDrv, PIC_IO_SET_REG, reg,2*sizeof(BYTE), NULL, 0, NULL,NULL);
    if(!ret_val)
        return TOUCH_STATUS_FAILURE;

    return TOUCH_STATUS_SUCCESS;
}


TOUCH_STATUS_T ReadMiccoReg(BYTE reg_address, BYTE *value)
{
    BOOL ret_val;
    BYTE reg[2];	

    if (!value) return TOUCH_STATUS_FAILURE;
	
    reg[0] = reg_address;

    ret_val = DeviceIoControl(g_hMiccoDrv, PIC_IO_GET_REG, reg, sizeof(BYTE), reg+1, sizeof(BYTE), NULL, NULL);

    if (!ret_val) return TOUCH_STATUS_FAILURE;

    *value = reg[1];
	
    //RETAILMSG(DEBUG_TOUCH,(TEXT("[TOUCH] ReadMiccoReg[%2x]=%02x\r\n"), reg_address, *value));
    return TOUCH_STATUS_SUCCESS;
}


TOUCH_STATUS_T	TsiRead_X_Y(int *X, int *Y)
{

	BYTE reg[2];
		
	//read TSI_X_MSB
	reg[0] = XLLP_MICCO_TSI_X_MSB;
	if ( !DeviceIoControl(g_hMiccoDrv, PIC_IO_GET_REG, reg,sizeof(BYTE), reg+1, sizeof(BYTE), NULL,NULL))
	    return TOUCH_STATUS_FAILURE;
				
	*X = (reg[1]);
	*X = (*X<<2);

	//read TSI_Y_MSB
	reg[0] = XLLP_MICCO_TSI_Y_MSB;
	if (!DeviceIoControl(g_hMiccoDrv, PIC_IO_GET_REG, reg,sizeof(BYTE), reg+1, sizeof(BYTE), NULL,NULL))
	    return TOUCH_STATUS_FAILURE;
				
	*Y = (reg[1]);
	*Y = (*Y<<2);

	//*Y = reg[1];//-0x12;

	//read TSI_X_PLUS_Y_LSB
	reg[0] = XLLP_MICCO_TSI_XY_MSB;
	if ( !DeviceIoControl(g_hMiccoDrv, PIC_IO_GET_REG, reg,sizeof(BYTE), reg+1, sizeof(BYTE), NULL,NULL))
	    return TOUCH_STATUS_FAILURE;
		
	*X = (*X|(reg[1]&TSI_X_MASK));
	*Y = (*Y|(reg[1]&TSI_Y_MASK)>>2);

	TSP_TransXY(X,Y);

	return TOUCH_STATUS_SUCCESS;
}

static BOOL EnableTSI_LDO(void)
{
   
    TOUCH_STATUS_T ret;
    //Start:Enable LDO_ADC_ENABLE & tune MUX to TSI @  XLLP_MICCO_ADC_MAN_CONTROL
    ret = ModifyMiccoReg(XLLP_MICCO_ADC_MAN_CONTROL,  LDO_ADC_ENABLE_SET,MUX_MASK_CLR,NULL);
    if ( ret!= TOUCH_STATUS_SUCCESS)
    {
        RETAILMSG(DEBUG_TOUCH,(TEXT("[TOUCH] SetMiccoTSI ModifyMiccoReg failed\r\n")));
    }
    return(ret== TOUCH_STATUS_SUCCESS);
}


//----------------------------------------------------------------------------------------
//shacharh
//----------------------------------------------------------------------------------------


DWORD TouchISTThread(void* pParam)
{
    DWORD	dwTimeout = INFINITE;
    DWORD	waitStatus;


    HANDLE waitHandle[2]={g_PenDownEvent,g_hTouchIST_TerminateEvent}; // 0  - Micco Event, 1 - Terminate Thread

    BOOL bLoop = TRUE;
	

    //RETAILMSG(1, (TEXT("[TOUCH] +TouchISTThread Started\r\n"))); 
    while(bLoop)
    {
		
        waitStatus = WaitForMultipleObjects(2,waitHandle,FALSE,dwTimeout);
        switch(waitStatus){		
        case WAIT_TIMEOUT:
            //RETAILMSG(1, (TEXT("[TOUCH] TouchISTThread  Timeout\n"))); 
            return(0);
        case WAIT_OBJECT_0: //g_PenDownEvent[0] event occured.
            //RETAILMSG(1, (TEXT("[TOUCH] TouchISTThread  pen down event detect.\n"))); 
             //Sleep(5);
		penStatus = GetPenStatus();		
		if(penStatus==PEN_STATUS_DOWN){
			//RETAILMSG(1, (L"[TOUCH] Pen down event detect.\r\n"));
			//DisablePenDownInterrupt();
			// tell MDD to call DdsiTouchPanelGetPoint to sample touch cordinate
			SetEvent(hTouchPanelEvent);
		}/*
		else if(penStatus == PEN_STATUS_UP){
			//RETAILMSG(1, (L"[TOUCH] Pen up event detect.\r\n"));
		}*/
		//SetEvent(hTouchPanelEvent);

		break;
        case (WAIT_OBJECT_0+1):
            bLoop = FALSE;
            break;
        default:
            break;		
        }//switch 
    }//while

    //interrupt here can be only received from MICCO ( GPIO Interrupt ) 
	
    //RETAILMSG(1, (TEXT("[TOUCH] -TouchISTThread Terminated\n"))); 
    return(1);
}


//----------------------------------------------------------------------------------------
//shacharh
//----------------------------------------------------------------------------------------
static TOUCH_PANEL_SAMPLE_FLAGS PDDSampleTouchScreen(INT *x,INT *y)
{

	UINT32 i;

	TOUCH_PANEL_SAMPLE_FLAGS TmpStateFlags;
	TOUCHPANEL_POINT_SAMPLES rgPointSamples;
	int TmpX = 0;
	int TmpY = 0;  
	//DWORD res;

	//RETAILMSG(1,(TEXT("+Touch panel PDD Sample Touch Screen - Start\r\n")));

	//TSI is in PEN_DETECTION mode & also Time Int in case pen_down state is enable 
	//, in order to get x,y reading we need to :

	// 0.disable touch int 
	// 1. switch to AUTO TSI ( while disabling and mask out PEN_DETECT
	// 2.wait for TSI Ready EVENT, meaning we have valid reading from ADC  
	// 3. read X,Y coordinates and validate 
	// 4. switch back to PEN_DETECTION, un-mask PEN_DETECT Inter.
	// 5.wait for pen_detect event, since pen event might occur during measurment
	if( penStatus==PEN_STATUS_INIT)
	{
		EnablePenDownInterrupt();
		TmpStateFlags = TouchSampleIgnore;
		return TmpStateFlags;
	}
	
	// 1.1- Disable pen detect interrupt
	DisablePenDownInterrupt();
	// 1.2 - reset the event for TSI ready, cleat any previous signaling
	//ResetEvent(g_TSI_X_Y_ReadyEvent);
	// 1.3 Set TSI Mode and enabler interrupt
	SetMiccoTSIMode(TSI_AUTO);
	//Sleep(1);
/*	EnableTSI_X_Y_ReadyInterrupt();

	// 1.4 wait for AUTO_TSI ready event
	res = WaitForSingleObject(g_TSI_X_Y_ReadyEvent,INFINITE);
	// 1.5 
	if ( res==WAIT_TIMEOUT)
	{
		//we could not get a valid reading - return ignore
		RETAILMSG(DEBUG_TOUCH,(TEXT("[TOUCH] ERROR, TSI_READY TIMEOUT\r\n")));
		TmpStateFlags |= TouchSampleIgnore;
		return TmpStateFlags;
	}
	else
	{
		DisableTSI_X_Y_ReadyInterrupt();
		RETAILMSG(1,(L"[TOUCH] TSI_READY interrupt\r\n"));		
	}*/

	for (i=0;i<TOUCH_SAMPLES_NUMBER_PER_POINT;i++)             // Prime the Pump for the X and Y
	{
		//if here we can safely read X,Y
		// 1.6 
		if (TsiRead_X_Y(&TmpX,&TmpY)!=TOUCH_STATUS_SUCCESS)
		{
		    RETAILMSG(DEBUG_TOUCH,(TEXT("[TOUCH] ERROR, Could not read X,Y from MICCO\r\n")));
		    TmpStateFlags |= TouchSampleIgnore;
		    return TmpStateFlags;
		}

		rgPointSamples[i].XSample=TmpX;  
		rgPointSamples[i].YSample=TmpY;  
	}
	
	TmpStateFlags = TouchSampleDownFlag;
	if (evaluateSample(&rgPointSamples[0].XSample,
	               DELTA_X_COORD_VARIANCE,&TmpX) == TouchSampleIgnore)
	{
		TmpStateFlags |= TouchSampleIgnore;
		//        RETAILMSG(1,(TEXT("Invalid X sample\r\n")));
	}
	else
	{
		if (evaluateSample(&rgPointSamples[0].YSample,
		               DELTA_Y_COORD_VARIANCE,&TmpY) == TouchSampleIgnore)
		{
			TmpStateFlags |= TouchSampleIgnore;
			//            RETAILMSG(1,(TEXT("Invalid Y sample\r\n")));
		}
		else
		{
			TmpStateFlags |= TouchSampleValidFlag;

			g_prevX=TmpX;
			g_prevY=TmpY;
		}
	}

	//////////////////////////////////////////////////////////////////////////

	*x=TmpX;
	*y=TmpY;
	
	//DisableTSI_X_Y_ReadyInterrupt();

	//now we can switch back to PEN_DETECT Mode
	SetMiccoTSIMode(TSI_PEN_DETECT);

	//XllpOstDelayMilliSeconds(g_pOSTRegs,5);
	Sleep(3);
	penStatus = GetPenStatus();
	if(penStatus==PEN_STATUS_UP)
	{
		*x = g_prevX;
		*y = g_prevY;
		TmpStateFlags=TouchSampleValidFlag;
		EnablePenDownInterrupt();
		InterruptDone(gIntrTouch);
		//RETAILMSG(DEBUG_TOUCH,(TEXT("[TOUCH] x=%d, y=%d,tateFlags=0x%x\r\n"),*x,*y,TmpStateFlags));
	}
	
	//RETAILMSG(DEBUG_TOUCH,(TEXT("[TOUCH] x=%d, y=%d,tateFlags=0x%x\r\n"),*x,*y,TmpStateFlags));
	
	return(TmpStateFlags);
}


BOOL DdsiTouchPanelEnable(void)
{
	//Sequence for enable TSI
	// 1. Set up TSI registers in Micco 
	//  2. Enable Interrupt from Micco Driver
      DWORD threadID;

	//RETAILMSG(1, (TEXT("[TOUCH] +TSI_MICCO_B0_DdsiTouchPanelEnable Touch panel Enable Start\r\n"))); 

	PHYSICAL_ADDRESS RegPA;
	if (g_pOSTRegs == NULL)
	{
	     RegPA.QuadPart = MONAHANS_BASE_REG_PA_OST;
	     g_pOSTRegs = (P_XLLP_OST_T) MmMapIoSpace(RegPA, sizeof(XLLP_OST_T), FALSE);
	}

	if ( g_hMiccoDrv==NULL)
	{
	    //obtain micco driver handle
	    g_hMiccoDrv=CreateFile(PIC_FILE_NAME, 0, 0, NULL, 0, 0, NULL);
	    //map OST registers
	    if (g_hMiccoDrv == INVALID_HANDLE_VALUE)
	    {
	        RETAILMSG(DEBUG_TOUCH,(TEXT("+Touch panel Enable error - INVALID_HANDLE_VALUE Micco Drv\r\n")));
	        return FALSE;
	  }
	}

	EnableTSI_LDO();
	// TSI_delay: 3 slot: TSI_SKIP: 3 slot 
	ModifyMiccoReg(XLLP_MICCO_TSI_CONTROL_1, 0x60, 0xff, NULL);
	ModifyMiccoReg(XLLP_MICCO_TSI_CONTROL_2, 0x00, 0xff, NULL);
	ModifyMiccoReg(XLLP_MICCO_ADC_AUTO_CONTROL_1, 0x2e, 0xff, NULL);

/*
	ModifyMiccoReg(XLLP_MICCO_ADC_AUTO_CONTROL_2, 0x18, 0xff, NULL);
	ModifyMiccoReg(XLLP_MICCO_TSI_CONTROL_2, 0x80, 0xff, NULL);
	Sleep(40);
	ModifyMiccoReg(XLLP_MICCO_ADC_AUTO_CONTROL_2, 0x10, 0xff, NULL);
*/
	//create the IST
	g_hTouchIST = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)TouchISTThread,NULL,0,&threadID);
	if (!g_hTouchIST)
	    RETAILMSG(1, (_T("[touch]: ERROR: Can't create touch thread\r\n")));
	else
	    RETAILMSG(1, (_T("[Touch]: Created thread successfully\r\n")));

	g_hTouchIST_TerminateEvent = CreateEvent(NULL,FALSE,FALSE,NULL);

	//enable Micco Intrrupt
	EnablePenDownInterrupt();
	if(!SetMiccoTSIMode(TSI_PEN_DETECT))
	{
	    RETAILMSG(1, (_T("ERROR: Touch panel Enable can't SetMiccoTSI Err\r\n")));
	    return FALSE;
	}
	
    //XllpINTCEnableSource(XLLP_INTC_S_OST_M1,XLLP_TRUE);

	return(TRUE);
}

//------------------------------------------------------------------------------
//shacharh MICCO B0
//------------------------------------------------------------------------------

void DdsiTouchPanelDisable(void)
{
        //directly return from here, which touch can work after run LTK4020/4080.
       // return;

	if ( g_hMiccoDrv==NULL)
	    return; // TSI_MICCO_B0_DdsiTouchPanelEnable was not called yet, just return

	//Sequence for disable TSI
	// 1. disable Interrupt from Micco Driver
	// 2. Clear TSI registers in Micco 

	//RETAILMSG(1, (TEXT("[TOUCH] +TSI_MICCO_B0_DdsiTouchPanelDisable Touch panel Disable Start\r\n")));

	if ( g_hTouchIST_TerminateEvent!=NULL)
	{
	    //disable Micco Intrrupt - PMIC_INT (GPIO18)
	    DisablePenDownInterrupt();
	    //Kill the IST thread
	    //signal the thread it should terminate 
	    SetEvent(g_hTouchIST_TerminateEvent);
	    WaitForSingleObject(g_hTouchIST,INFINITE);
	    CloseHandle(g_hTouchIST);
	    g_hTouchIST = NULL;
	    //close and release event hadle 
	    CloseHandle(g_hTouchIST_TerminateEvent);
	    g_hTouchIST_TerminateEvent=NULL;
	    if(!ClearMiccoTSI())
	        RETAILMSG(1, (_T("ERROR:TouchPanelDisable can't DeallocateTouchPanelResources Err\r\n")));

	    //unmap ost registers
	    if (g_pOSTRegs != NULL)
	    {
	        MmUnmapIoSpace(g_pOSTRegs, sizeof(XLLP_OST_T));
	    }
	}


	//RETAILMSG(1, (TEXT("[TOUCH] -TSI_MICCO_B0_DdsiTouchPanelDisable Touch panel Disable End\r\n"))); 
	return;
}

//------------------------------------------------------------------------------
//shacharh MICCO B0
//------------------------------------------------------------------------------

void DdsiTouchPanelPowerHandler(BOOL PowerOff)
{
	RETAILMSG(DEBUG_TOUCH,(TEXT("+Touch panel power handler Start\r\n")));
	RETAILMSG(DEBUG_TOUCH,(TEXT("-Touch panel power handler End\r\n")));	
	return;
}

//------------------------------------------------------------------------------
//shacharh MICCO B0 - Called from tchbasic -> DLL_PROCESS_ATTACH
//------------------------------------------------------------------------------
LONG DdsiTouchPanelAttach()
{
    RETAILMSG(1,(_T("+ DdsiTouchPanelAttach\r\n")));
    RETAILMSG(1,(_T("- DdsiTouchPanelAttach\r\n")));
    return(0);
}

//------------------------------------------------------------------------------
//shacharh MICCO B0 - Called from tchbasic -> DLL_PROCESS_DETACH
//------------------------------------------------------------------------------
LONG DdsiTouchPanelDetach()
{
	RETAILMSG(1,(_T("+ DdsiTouchPanelDettach\r\n")));
	RETAILMSG(1,(_T("- DdsiTouchPanelDetach\r\n")));
	return(0);
}
//------------------------------------------------------------------------------
//shacharh MICCO B0
//------------------------------------------------------------------------------
BOOL DdsiTouchPanelGetDeviceCaps(INT iIndex,LPVOID  lpOutput)
{
	//RETAILMSG(DEBUG_TOUCH,(TEXT("+ TSI_MICCO_B0_DdsiTouchPanelGetDeviceCaps Touch panel Get DeviceCaps Start\r\n")));
	if (lpOutput == NULL)
	{
	    ERRORMSG(1,(__TEXT("TouchPanelGetDeviceCaps: invalid parameter.\r\n")));
	    SetLastError(ERROR_INVALID_PARAMETER);
	    RETAILMSG(DEBUG_TOUCH,(TEXT("-Touch panel Get DeviceCaps false 1\r\n")));
	    return (FALSE);
	}

	switch (iIndex)
	{
	case TPDC_SAMPLE_RATE_ID:
	    {
	        TPDC_SAMPLE_RATE  *pTSR = (TPDC_SAMPLE_RATE*)lpOutput;

	        pTSR->SamplesPerSecondLow = TOUCHPANEL_SAMPLE_RATE_LOW;
	        pTSR->SamplesPerSecondHigh = TOUCHPANEL_SAMPLE_RATE_HIGH;
	        pTSR->CurrentSampleRateSetting = TOUCHPANEL_SAMPLE_RATE_HIGH;
	    }
	    break;

	case TPDC_CALIBRATION_POINT_COUNT_ID:
	    {
	        TPDC_CALIBRATION_POINT_COUNT *pTCPC = (TPDC_CALIBRATION_POINT_COUNT*)lpOutput;
	        pTCPC->flags = 0;
	        pTCPC->cCalibrationPoints = 5;
	    }
	    break;

	case TPDC_CALIBRATION_POINT_ID:
	    RETAILMSG(DEBUG_TOUCH,(TEXT("-Touch panel Get DeviceCaps TPDC_CALIBRATION_POINT_ID\r\n")));
		return(TouchDriverCalibrationPointGet((TPDC_CALIBRATION_POINT*)lpOutput));

	default:
	    ERRORMSG(1,(__TEXT("TouchPanelGetDeviceCaps: invalid parameter.\r\n")));
	    SetLastError(ERROR_INVALID_PARAMETER);
	    RETAILMSG(DEBUG_TOUCH,(TEXT("-Touch panel Get DeviceCaps false 2\r\n")));
	    return (FALSE);
	}
	//RETAILMSG(DEBUG_TOUCH,(TEXT("- TSI_MICCO_B0_DdsiTouchPanelGetDeviceCaps Touch panel Get DeviceCaps End\r\n")));
	return (TRUE);
}

//------------------------------------------------------------------------------
//shacharh MICCO B0
//------------------------------------------------------------------------------

BOOL DdsiTouchPanelSetMode(INT iIndex,LPVOID  lpInput)
{
	BOOL  ReturnCode = FALSE;

	//RETAILMSG(DEBUG_TOUCH,(TEXT("+Touch panel Set mode Start\r\n")));
	switch (iIndex)
	{
	case TPSM_SAMPLERATE_LOW_ID:
	case TPSM_SAMPLERATE_HIGH_ID:
	    SetLastError(ERROR_SUCCESS);
	    ReturnCode = TRUE;
	    break;

	default:
	    SetLastError(ERROR_INVALID_PARAMETER);
	    break;
	}
	//RETAILMSG(DEBUG_TOUCH,(TEXT("-Touch panel Set mode End\r\n")));
	return(ReturnCode);
}

//------------------------------------------------------------------------------
//shacharh MICCO B0
//------------------------------------------------------------------------------

void DdsiTouchPanelGetPoint(TOUCH_PANEL_SAMPLE_FLAGS *pTipStateFlags, INT *pUncalX, INT *pUncalY)
{

	//RETAILMSG(1,(TEXT("[touch] + TSI_MICCO_B0_DdsiTouchPanelGetPoint Start \r\n")));

	if (!pTipStateFlags || !pUncalX || !pUncalY)
	{
	    DEBUGMSG(DEBUG_TOUCH, (TEXT("ERROR: TSI_MICCO_B0_DdsiTouchPanelGetPoint: Invalid parameter(s).\r\n")));
	    return;
	}

	*pTipStateFlags = PDDSampleTouchScreen(pUncalX, pUncalY);
	
	if ( penStatus==PEN_STATUS_INIT)
	{
	    *pTipStateFlags = TouchSampleIgnore;
	}

	if ( *pTipStateFlags&TouchSampleDownFlag)
	{
	    EnableTouchTimerInterrupt(TOUCH_TIMER_INCREMENT_TSI_OSMR1);
	    InterruptDone(gIntrTouchChanged);
	}

/*	if ( penStatus==PEN_STATUS_DOWN){
	    InterruptDone(gIntrTouchChanged);
	}
	else if(penStatus==PEN_STATUS_UP){
		InterruptDone(gIntrTouch);
		//RETAILMSG(1, (L"MDD Pen UP: x(%d),y(%d),Flags(0x%x)\r\n",*pUncalX,*pUncalY,*pTipStateFlags));		
	}*/
		

	//RETAILMSG(DEBUG_TOUCH,(_T("[touch] - TSI_MICCO_B0_DdsiTouchPanelGetPoint  End\r\n")));
}

//------------------------------------------------------------------------------
//shacharh MICCO B0
//------------------------------------------------------------------------------


BOOL TouchDriverCalibrationPointGet(TPDC_CALIBRATION_POINT *pTCP)
{
    INT32 cDisplayWidth = pTCP->cDisplayWidth;
    INT32 cDisplayHeight = pTCP->cDisplayHeight;

    int CalibrationRadiusX = cDisplayWidth/10;
    int CalibrationRadiusY = cDisplayHeight/10;

	//RETAILMSG(1,(_T("+ TouchDriverCalibrationPointGet\r\n")));

    switch (pTCP->PointNumber)
    {
    case  0:  // Middle
        pTCP->CalibrationX = cDisplayWidth/2;
        pTCP->CalibrationY = cDisplayHeight/2;
        break;

    case  1:  // Upper Left
        pTCP->CalibrationX = CalibrationRadiusX*2;
        pTCP->CalibrationY = CalibrationRadiusY*2;
        break;

    case  2:  // Lower Left
        pTCP->CalibrationX = CalibrationRadiusX*2;
        pTCP->CalibrationY = cDisplayHeight - CalibrationRadiusY*2;
        break;

    case  3:  // Lower Right
        pTCP->CalibrationX = cDisplayWidth - CalibrationRadiusX*2;
        pTCP->CalibrationY = cDisplayHeight - CalibrationRadiusY*2;
        break;

    case  4:  // Upper Right
        pTCP->CalibrationX = cDisplayWidth - CalibrationRadiusX*2;
        pTCP->CalibrationY = CalibrationRadiusY*2;
        break;

    default:
        pTCP->CalibrationX = cDisplayWidth/2;
        pTCP->CalibrationY = cDisplayHeight/2;
        SetLastError(ERROR_INVALID_PARAMETER);
        return (FALSE);
    }


	//RETAILMSG(1,(_T("- TouchDriverCalibrationPointGet\r\n")));
    return (TRUE);
}

//------------------------------------------------------------------------------
//shacharh MICCO B0
//------------------------------------------------------------------------------

extern"C" BOOL TouchPanelDllEntry(
    HANDLE hDllHandle,
    DWORD  dwReason,
    LPVOID lpReserved
    );

extern "C" BOOL DllEntry(
    HANDLE hDllHandle,
    DWORD  dwReason,
    LPVOID lpReserved
    )
{
       return TouchPanelDllEntry(hDllHandle,dwReason,lpReserved);
}

//------------------------------------------------------------------------------

//shacharh end
